package language.advanced.Concurrent;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

//使用阻塞队列处理生产者消费者问题
class BlockingQueueTest {

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> bQueue = new LinkedBlockingQueue<>(3);

        Thread Consumer = new Thread(){
            @Override
            public void run(){
                try {
                    //先等待一段时间，bQueue.add("a")模拟生产者
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者正式启动");
                while (true) {
                    try {
                        String msg = (String) bQueue.take();
                        System.out.println(msg);
                    } catch (Exception e) {
                        //take方法如果取不到元素，会阻塞以让出cpu占用权，所以这里走不到
                        //take改成remove就能走到
                        //take的异常为中断异常
                        System.out.println("队列中已经没有元素了");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            }
        };

        //启动消费者，这个消费者会不断地消费
        Consumer.start();
        bQueue.add("a");
        bQueue.add("a");
        bQueue.add("a");

        while (true) {
            try {
                //不停地添加第四个，因为阻塞队列大小为3，所以无法添加并报异常
                bQueue.add("a");
                //这句话可能在第四个a之前或之后打印。因为消费者线程不是本线程
                System.out.println("成功添加第四个a，生产者等待消费者消费完");
                break;
            } catch (IllegalStateException e) {
                //add方法会抛出异常，所以能走到这里
                System.out.println("阻塞队列已满");
            }
        }

        //等待消费者把队列里的内容给消费完
        Thread.sleep(2000);
        System.out.println("消费者已消费完四个a");
        bQueue.add("b");  //打印b
        bQueue.add("c");  //打印c

    }
}




